home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
MLT_TASK
/
MULTIP
/
MULTI.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1994-07-19
|
3KB
|
98 lines
Unit Multi;
{--------------------------------------------------------------------------------}
{ }
{ Hilfsfunktionen zur quasi-Multitaskingverarbeitung unter Turbo Pascal }
{ }
{ (c) 1994 by Hegel Udo }
{ }
{--------------------------------------------------------------------------------}
Interface
{--------------------------------------------------------------------------------}
Type
StartProc = Procedure;
{--------------------------------------------------------------------------------}
Procedure AddTask (Start : StartProc;StackSize : Word);
Procedure Transfer;
{--------------------------------------------------------------------------------}
Implementation
{--------------------------------------------------------------------------------}
Uses
Dos;
{--------------------------------------------------------------------------------}
Type
TaskPtr = ^TaskRec;
TaskRec = Record
StackSize : Word;
Stack : Pointer;
SPSave : Word;
SSSave : Word;
BPSave : Word;
Next : TaskPtr;
end;
{--------------------------------------------------------------------------------}
Const
MinStack = 1024;
MaxStack = 32768;
{--------------------------------------------------------------------------------}
Var
Tasks : TaskPtr;
AktTask : TaskPtr;
OldExit : Pointer;
{--------------------------------------------------------------------------------}
Procedure AddTask (Start : StartProc;StackSize : Word);
Type
OS = Record
O,S : Word;
end;
Var
W : ^TaskPtr;
SS : Word;
SP : Word;
begin
W := @Tasks;
While Assigned (W^) do W := @W^^.Next;
New (W^);
if StackSize < MinStack then StackSize := MinStack;
if StackSize > MaxStack then StackSize := MaxStack;
W^^.StackSize := StackSize;
GetMem (W^^.Stack,StackSize);
SS := OS(W^^.Stack).S;
SP := OS(W^^.Stack).O+StackSize-4;
Move (Start,Ptr(SS,SP)^,4);
W^^.SPSave := SP;
W^^.SSSave := SS;
W^^.BPSave := W^^.SPSave;
W^^.Next := NIL;
end;
{--------------------------------------------------------------------------------}
Procedure Transfer; Assembler;
Asm
LES SI,AktTask { Alter Status sichern }
MOV ES:[SI].TaskRec.SPSave,SP
MOV ES:[SI].TaskRec.SSSave,SS
MOV ES:[SI].TaskRec.BPSave,BP
MOV AX,Word Ptr ES:[SI].TaskRec.Next { Neue Task bestimmen }
OR AX,Word Ptr ES:[SI].TaskRec.Next+2
JE @InitNew
LES SI,ES:[SI].TaskRec.Next
JMP @DoJob
@InitNew:
LES SI,Tasks
@DoJob:
MOV Word Ptr AktTask,SI { Neue Task Sichern }
MOV Word Ptr AktTask+2,ES
CLI { Status wieder hertstellen }
MOV SP,ES:[SI].TaskRec.SPSave
MOV SS,ES:[SI].TaskRec.SSSave
STI
MOV BP,ES:[SI].TaskRec.BPSave
end;
{--------------------------------------------------------------------------------}
BEGIN
New (Tasks); { Hauptprogramm als Task anmelden }
Tasks^.StackSize := 0;
Tasks^.Stack := NIL;
Tasks^.Next := NIL;
AktTask := Tasks;
END.